<script setup lang="ts">
import { h, ref, reactive, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { NModal, NCard, NForm, NSpace, NFormItem, NInput, NSelect, NInputNumber, NButton, NDataTable, NPagination, NPopconfirm, useNotification } from 'naive-ui'
import type { FormInst, FormRules } from 'naive-ui'

import { useDictStore } from '@/stores/dictStore'
import http from '@/tools/http'

type RowData = {
    serverName?: string
    serverHost?: string
    serverPort?: number
    serverUsername: string
    serverPwdType?: string
    serverPassword?: string
    remark?: string
}

const router = useRouter()
const dictStore = useDictStore()

const serverTableColumns = [
    {
        title: "服务器名称",
        key: "serverName"
    }, {
        title: "服务器HOST",
        key: "serverHost"
    }, {
        title: "服务器PORT",
        key: "serverPort"
    }, {
        title: "服务器用户名",
        key: "serverUsername"
    }, {
        title: "密码类型",
        key: "serverPwdType",
        render(rowData: RowData, rowIndex: number) {
            return dictStore.dictItem("SERVER_PWD_TYPE", rowData.serverPwdType)
        }
    }, {
        title: "服务器密码",
        key: "serverPassword",
        render(rowData: RowData, rowIndex: number) {
            let str = ""
            if (rowData.serverPassword) {
                for (let i = 0; i < rowData.serverPassword.length; i++) {
                    str += "*"
                }
                return str
            } else {
                return rowData.serverPassword
            }
        }
    }, {
        title: "备注",
        key: "remark"
    }, {
        title: "操作",
        key: "actions",
        width: "281px",
        render(rowData: RowData, rowIndex: number) {
            return h(
                NSpace, null,
                () => [
                    h(
                        NButton,
                        {
                            size: "small",
                            onclick: () => openEditServer(rowData)
                        },
                        { default: () => "PIPELINE" }
                    ),
                    h(
                        NButton,
                        {
                            size: "small",
                            onclick: () => openServerSsh(rowData)
                        },
                        { default: () => "SSH" }
                    ),
                    h(
                        NButton,
                        {
                            size: "small",
                            onclick: () => openEditServer(rowData)
                        },
                        { default: () => "编辑" }
                    ),
                    h(
                        NPopconfirm,
                        {
                            onPositiveClick: (e: MouseEvent) => deleteServer()
                        },
                        {
                            trigger: () => {
                                return h(
                                    NButton,
                                    {
                                        size: "small",
                                        onclick: () => openDeleteServer(rowData)
                                    },
                                    { default: () => "删除" }
                                )
                            },
                            default: () => { return "确认删除？" }
                        }
                    )
                ]
            )
        }
    }
]

const serverData = reactive<any>({
    list: [],
    pageNum: 1,
    pageSize: 10,
    pages: 1,
    total: 0
})

const serverSearchFormValue = reactive({
    pageNum: 1,
    pageSize: 10,
    serverName: "",
    serverHost: ""
})

onMounted(() => {
    pageServer()
})

const visiable = ref<boolean>(false)
const title = ref<string>("")
const formRef = ref<FormInst | null>(null)
const formData = reactive<RowData>({
    serverName: "",
    serverHost: "",
    serverPort: 22,
    serverUsername: "",
    serverPwdType: "",
    serverPassword: "",
    remark: ""
})

const formRules: FormRules = ({
    serverName: {
        required: true,
        message: '请输入服务器名称',
        trigger: ['input']
    },
    serverHost: {
        required: true,
        message: '请输入服务器HOST',
        trigger: ['input']
    },
    serverPort: {
        type: 'number',
        required: true,
        message: '请输入服务器PORT',
        trigger: ['input']
    },
    serverUsername: {
        required: true,
        message: '请输入服务器用户名',
        trigger: ['input']
    },
    serverPwdType: {
        required: true,
        message: '请输入密码类型',
        trigger: ['input']
    },
    serverPassword: {
        required: true,
        message: '请输入服务器密码',
        trigger: ['input']
    }
})

function pageNumChange(pageNum: number) {
    serverSearchFormValue.pageNum = pageNum
    pageServer()
}

function pageSizeChange(pageSize: number) {
    serverSearchFormValue.pageSize = pageSize
    pageServer()
}

function openAddServer() {
    visiable.value = true
    title.value = "添加主机信息表"
    formData.serverName = ""
    formData.serverHost = ""
    formData.serverPort = 22
    formData.serverUsername = ""
    formData.serverPwdType = "0"
    formData.serverPassword = ""
    formData.remark = ""
}

function openEditServer(row: RowData) {
    visiable.value = true
    title.value = "编辑主机信息表"
    formData.serverName = row.serverName
    formData.serverHost = row.serverHost
    formData.serverPort = row.serverPort
    formData.serverUsername = row.serverUsername
    formData.serverPwdType = row.serverPwdType
    formData.serverPassword = row.serverPassword
    formData.remark = row.remark
}

function openDeleteServer(row: RowData) {
    formData.serverName = row.serverName
    formData.serverHost = row.serverHost
    formData.serverPort = row.serverPort
    formData.serverUsername = row.serverUsername
    formData.serverPwdType = row.serverPwdType
    formData.serverPassword = row.serverPassword
    formData.remark = row.remark
}

function openServerSsh(row: RowData) {
    router.push({
        name: 'remote-server-ssh',
        query: { serverName: row.serverName }
    })
}

function submit() {
    formRef.value?.validate((errors) => {
        if (!errors) {
            if (title.value === "添加主机信息表") {
                addServer()
            } else {
                updateServer()
            }
            visiable.value = false
        }
    })
}

function pageServer() {
    http.post("/server/page", serverSearchFormValue).then(({ data }) => {
        serverData.pageNum = data.data.pageNum
        serverData.pageSize = data.data.pageSize
        serverData.pages = data.data.pages
        serverData.total = data.data.total
        serverData.list.length = 0
        for (let i = 0; i < data.data.list.length; i++) {
            serverData.list.push(data.data.list[i])
        }
    })
}

const notification = useNotification()

function addServer() {
    http.post("/server/add", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '添加成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageServer()
        }
    })
}

function updateServer() {
    http.post("/server/update", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '修改成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageServer()
        }
    })
}

function deleteServer() {
    http.post("/server/delete", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '删除成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageServer()
        }
    })
}

function testConnection() {
    http.post("/server/connection/test", formData).then(({ data }) => {
        if (data.code === "0") {
            notification['success']({
                content: '连接成功',
                meta: `${data.msg}`,
                duration: 2500,
                keepAliveOnHover: true
            })
            pageServer()
        }
    })
}
</script>

<template>
    <div class="flame-container">
        <n-card title="主机信息表" :content-style="{ overflowY: 'auto' }" :bordered="false">
            <n-form :model="serverSearchFormValue" inline label-placement="left">
                <n-form-item label="服务器名称" path="serverName">
                    <n-input v-model:value="serverSearchFormValue.serverName" placeholder="请输入服务器名称" clearable />
                </n-form-item>
                <n-form-item label="服务器HOST" path="serverHost">
                    <n-input v-model:value="serverSearchFormValue.serverHost" placeholder="请输入服务器HOST" clearable />
                </n-form-item>
                <n-form-item>
                    <n-button attr-type="button" @click="pageServer()">查询</n-button>
                </n-form-item>
            </n-form>
            <n-space vertical>
                <n-button attr-type="button" @click="openAddServer()">新增</n-button>
                <n-data-table :columns="serverTableColumns" :data="serverData.list" :bordered="false" />
            </n-space>
            <template #footer>
                <div class="display-flex-end">
                    <n-pagination v-model:page="serverData.pageNum" :page-size="serverData.pageSize"
                        :item-count="serverData.total" :page-sizes="[5, 10, 30, 50, 100]"
                        :on-update-page="pageNumChange" :on-update-page-size="pageSizeChange" show-quick-jumper
                        show-size-picker />
                </div>
            </template>
        </n-card>
    </div>
    <n-modal v-model:show="visiable">
        <n-card style="width: 500px" :title="title">
            <n-form ref="formRef" :model="formData" :rules="formRules" label-width="106px" label-placement="left"
                require-mark-placement="left">
                <n-form-item label="服务器名称" path="serverName">
                    <n-input v-model:value="formData.serverName" :disabled="title === '编辑主机信息表'" placeholder="请输入服务器名称"
                        clearable />
                </n-form-item>
                <n-form-item label="服务器HOST" path="serverHost">
                    <n-input v-model:value="formData.serverHost" placeholder="请输入服务器HOST" clearable />
                </n-form-item>
                <n-form-item label="服务器PORT" path="serverPort">
                    <n-input-number v-model:value="formData.serverPort" style="width:100%" placeholder="请输入服务器PORT"
                        :min="0" />
                </n-form-item>
                <n-form-item label="服务器用户名" path="serverUsername">
                    <n-input v-model:value="formData.serverUsername" :disabled="title === '编辑服务器用户名'"
                        placeholder="请输入服务器用户名" clearable />
                </n-form-item>
                <n-form-item label="密码类型" path="serverPwdType">
                    <n-select v-model:value="formData.serverPwdType" :options="dictStore.dict('SERVER_PWD_TYPE')"
                        placeholder="请输入密码类型" />
                </n-form-item>
                <n-form-item label="服务器密码" path="serverPassword">
                    <n-input type="password" show-password-on="click" v-model:value="formData.serverPassword"
                        placeholder="请输入服务器密码" clearable />
                </n-form-item>
                <n-form-item label="备注" path="remark">
                    <n-input v-model:value="formData.remark" placeholder="请输入备注" clearable />
                </n-form-item>
            </n-form>
            <template #footer>
                <n-space justify="end">
                    <n-button attr-type="button" @click="testConnection()">测试连接</n-button>
                    <n-button attr-type="button" @click="visiable = false">取消</n-button>
                    <n-button attr-type="button" @click="submit()">提交</n-button>
                </n-space>
            </template>
        </n-card>
    </n-modal>
</template>

<style scoped>
.display-flex-end {
    display: flex;
    width: 100%;
    justify-content: flex-end;
}
</style>